#include "ogl_image_cache.h"
#include "ogl_graphics.h"

#include "graphics/graphics_util.h"
#include "util/timer.h"				// log
#include "util/log.h"				// log
#include "util/common_macros.h"		// macros
#include "util/mmgr.h"	 

#include "../sleipner_config.h"

#ifdef _SDL2

    #include "SDL2/include/SDL.h"
	#ifdef WIN32
        #include "glee/glee.h"
        //#include "SDL-1.2.13/include/SDL_opengl.h"
    #else
#ifdef _OPENGLES2
        #include "SDL2/include/SDL_opengles2.h"
#else
	#include "SDL2/include/SDL_opengles.h"
#endif
    #endif

#else

    #ifndef _PLATFORM_IOS
        #include "SDL-1.2.13/include/SDL_opengl.h"
    #else
        #include "SDL-1.2.13/include/SDL_opengles.h"
    #endif

#endif

#include <cassert>

OglImageCache::OglImageCache() : 
	ImageCache(),
	m_Texture(0),
	m_Format(GL_RGBA)
{
	GetGraphics()->AddImageCache(this);
}

OglImageCache::~OglImageCache()
{
	if (GetGraphics())
	{
		GetGraphics()->DropImageCache(this);
		Flush();
	}
}

void		OglImageCache::Flush()
{
	glDeleteTextures(1,&m_Texture);

	
}
void		OglImageCache::Recreate()
{
	_LOG(MSG_INIT, "recreating render target " << m_Width << "x" << m_Height);
	Create(m_Width, m_Height, m_Depth);
}


void		OglImageCache::Create(int	Width, int Height, int Depth)
{
	
	if(m_Texture)
	{
		glDeleteTextures(1,&m_Texture);
		m_Texture = 0;
	}

	
	m_Width  = Width;
	m_Height = Height;
	m_Depth  = Depth;

	// Create Storage Space For Texture Data 
	unsigned int* Data = (unsigned int*)new GLuint[((Width * Height)* 4 * sizeof(unsigned int))];
#ifdef PLATFORM_WIN32
	ZeroMemory(Data,((Width * Height)* 4 * sizeof(unsigned int)));	// Clear Storage Memory
#else
	for(int i =0; i < Width * Height * 4; i++)
		Data[i] = 0;
#endif	

	glGenTextures(1, &m_Texture);								// Create 1 Texture
	glBindTexture(GL_TEXTURE_2D, m_Texture);					// Bind The Texture
	glTexImage2D(GL_TEXTURE_2D, 0, 4, Width, Height, 0,
				 GL_RGBA, GL_UNSIGNED_BYTE, Data);						// Build Texture Using Information In data
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

	delete [] Data;												// Release data
	
}

void		OglImageCache::SetTextureStage(int _TexStage)
{
	if(m_Texture == 0)
		return;

	glBindTexture( GL_TEXTURE_2D, m_Texture );
#ifdef _OPENGLES2   
   
    const GLuint TEXTURE_LOC = 0;
    glUniform1i(TEXTURE_LOC, 0);
#else
	glEnable( GL_TEXTURE_2D );
#endif
	
	
}

void		OglImageCache::ClearCache(COLOR c)
{
	glClearColor(ColorGetRf(c),ColorGetGf(c),ColorGetBf(c),ColorGetAf(c));
	glClear(GL_COLOR_BUFFER_BIT );
}

bool		OglImageCache::BeginCache()
{	

	return true;
}
void		OglImageCache::EndCache()
{
	while(glGetError() != GL_NO_ERROR);		// clear previous errors

	glBindTexture(GL_TEXTURE_2D,m_Texture);		// Bind To The Texture	
	//glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0 ,(GraphicsUtil::HEIGHT-m_Height), m_Width, m_Height, 0);
	glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0,0, m_Width, m_Height, 0);

	//glGetTexImage(GL_TEXTURE_2D ,0,GL_RGBA,GL_UNSIGNED_BYTE ,m_TextureData);
	//FlipTexture(&m_TextureData,m_Width,m_Height);
	//glBindTexture(GL_TEXTURE_2D, m_FlipTexture);					// Bind The Texture
	//glTexImage2D(GL_TEXTURE_2D, 0, 4, m_Width, m_Height, 0,
	//			 GL_RGBA, GL_UNSIGNED_BYTE, m_TextureData);		
	//glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
	//glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

	GLenum  ErrCode = glGetError();
	if (ErrCode != GL_NO_ERROR)    			
		bool testbreak = true;	
	


}

//void		OglImageCache::FlipTexture(unsigned char** Data,unsigned int Width,unsigned int Height)
//{
//
//	unsigned char* Temp = (unsigned char*)new GLuint[((Width * Height)* 4 * sizeof(unsigned char))];
//	ZeroMemory(Temp,((Width * Height)* 4 * sizeof(unsigned int)));	// Clear Temp Memory
//
//	unsigned int Size = Width * 4 * sizeof(unsigned char);
//	for (int i = 0;  i <(int) Height;  ++i)
//		 memcpy( Temp + (Height- i-1)* Size   , *Data + i* Size , Size);
//	
//	memcpy(*Data,Temp,sizeof(unsigned char)*4*Width*Height);
//
//	delete [] Temp;
//
//}



